/**
  ******************************************************************************
  * @file   pd_h_rtc.c
  * @author Chris
  * @since  2023/12/11
  *
  * @brief  Peripheral driver of RTC.
  *
  ******************************************************************************
  */
#include "stm32g4xx_ll_bus.h"
#include "stm32g4xx_ll_pwr.h"
#include "stm32g4xx_ll_rtc.h"
#include "stm32g4xx_ll_rcc.h"

/** region Declaration and Definition Region */


/** region Variables and Constants Region */
uint16_t PD_RTC_Time[] = {0x23, 0x12, 0x11, 0x22, 0x36, 0x30, 1};
/** endregion Variables and Constants Region */

/** region Function Declaration Region */
void PD_RTC_SetTime(void);
/** endregion Function Declaration Region */

/** endregion Declaration and Definition Region */



/** region public function region */

void PD_RTC_Init(void) {
    LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);

    /* Enable write access to Backup domain */
    LL_PWR_EnableBkUpAccess();

    // 开启 LSE 时钟并等待就绪后设置
    LL_RCC_LSE_Enable();
    while (LL_RCC_LSE_IsReady() != SET);
    LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSE);

    LL_RCC_EnableRTC();
    LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_RTCAPB);

    /* RTC init */
    LL_RTC_InitTypeDef LL_RTC_InitStruct = {0};
    LL_RTC_StructInit(&LL_RTC_InitStruct);
    LL_RTC_InitStruct.HourFormat = LL_RTC_HOURFORMAT_24HOUR;
    LL_RTC_InitStruct.AsynchPrescaler = 0;
    LL_RTC_InitStruct.SynchPrescaler = 32767;
    LL_RTC_Init(RTC, &LL_RTC_InitStruct);

    /* Initialize RTC and set the Time and Date */
    if (LL_RTC_BKP_GetRegister(RTC, LL_RTC_BKP_DR0) != 0x5A5A5A5A) {
        /* Data init */
        LL_RTC_DateTypeDef LL_RTC_DateStruct;
        LL_RTC_DATE_StructInit(&LL_RTC_DateStruct);
        LL_RTC_DateStruct.WeekDay = PD_RTC_Time[6];
        LL_RTC_DateStruct.Day = PD_RTC_Time[2];
        LL_RTC_DateStruct.Month = PD_RTC_Time[1];
        LL_RTC_DateStruct.Year = PD_RTC_Time[0];
        LL_RTC_DATE_Init(RTC, LL_RTC_FORMAT_BCD, &LL_RTC_DateStruct);

        /* Time init */
        LL_RTC_TimeTypeDef LL_RTC_TimeStruct;
        LL_RTC_TIME_StructInit(&LL_RTC_TimeStruct);
        LL_RTC_TimeStruct.TimeFormat = LL_RTC_TIME_FORMAT_AM_OR_24;
        LL_RTC_TimeStruct.Hours = PD_RTC_Time[3];
        LL_RTC_TimeStruct.Minutes = PD_RTC_Time[4];
        LL_RTC_TimeStruct.Seconds = PD_RTC_Time[5];
        LL_RTC_TIME_Init(RTC, LL_RTC_FORMAT_BCD, &LL_RTC_TimeStruct);

        // 写入标志位
        LL_RTC_BKP_SetRegister(RTC, LL_RTC_BKP_DR0, 0x5A5A5A5A);
    }

}

void PD_RTC_SetTime(void) {

}

void PD_RTC_ReadTime(void) {
    PD_RTC_Time[0] = LL_RTC_DATE_GetYear(RTC);
    PD_RTC_Time[1] = LL_RTC_DATE_GetMonth(RTC);
    PD_RTC_Time[2] = LL_RTC_DATE_GetDay(RTC);
    PD_RTC_Time[3] = LL_RTC_TIME_GetHour(RTC);
    PD_RTC_Time[4] = LL_RTC_TIME_GetMinute(RTC);
    PD_RTC_Time[5] = LL_RTC_TIME_GetSecond(RTC);
    PD_RTC_Time[6] = LL_RTC_DATE_GetWeekDay(RTC);
}

uint32_t PD_RTC_GetTime(void) {
    /* Combination of hours, minutes and seconds (Format: 0x00HHMMSS). */
    return LL_RTC_TIME_Get(RTC);
}

uint32_t PD_RTC_GetDate(void) {
    /* Combination of WeekDay, Day, Month and Year (Format: 0xWWDDMMYY). */
    return LL_RTC_DATE_Get(RTC);
}
/** endregion public function region */



/** region private function region */

/** endregion private function region */
